﻿
#region Using Directives.

using System;
using System.Drawing;
using System.Reflection;

#endregion

namespace GDFlacTool.Common
{
    [Serializable]
    public abstract class Track
    {
        #region Fields.

        //private readonly string _trackFormat = string.Empty;
        //private read

        #endregion

        #region Constructors.

        protected Track()
        {
            BitsPerSample = string.Empty;
            Trackrename = null;
            Encoder = string.Empty;
            SampleRate = string.Empty;
            Time = string.Empty;
            FullPath = string.Empty;
            FilePath = string.Empty;
            FileName = string.Empty;
            Album = string.Empty;
            Artist = string.Empty;
            Albumartist = string.Empty;
            Title = string.Empty;
            Year = string.Empty;
            Genre = string.Empty;
            Comment = string.Empty;
            TrackNumber = string.Empty;
            DiscNumber = string.Empty;
            Catalog = string.Empty;
            Isrc = string.Empty;
            ReleaseType = string.Empty;
            Composer = string.Empty;
            Originalartist = string.Empty;
            Copyright = string.Empty;
            Url = string.Empty;
            EncodedBy = string.Empty;
            Mood = string.Empty;
            Rating = string.Empty;
            Quality = string.Empty;
            Bpm = string.Empty;
            Lyrics = string.Empty;
            Conductor = string.Empty;
            Lyricist = string.Empty;
            OriginalLyricist = string.Empty;
            Label = string.Empty;
            RemixedBy = string.Empty;
            RadioStationName = string.Empty;
            AudioFileUrl = string.Empty;
            AuthorUrl = string.Empty;
            AudioSourceUrl = string.Empty;
            RadioStationUrl = string.Empty;
            BuyCdUrl = string.Empty;
        }

        protected Track(string path)
        {
            BitsPerSample = string.Empty;
            Trackrename = null;
            Encoder = string.Empty;
            SampleRate = string.Empty;
            Time = string.Empty;
            FilePath = string.Empty;
            FileName = string.Empty;
            Album = string.Empty;
            Artist = string.Empty;
            Albumartist = string.Empty;
            Title = string.Empty;
            Year = string.Empty;
            Genre = string.Empty;
            Comment = string.Empty;
            TrackNumber = string.Empty;
            DiscNumber = string.Empty;
            Catalog = string.Empty;
            Isrc = string.Empty;
            ReleaseType = string.Empty;
            Composer = string.Empty;
            Originalartist = string.Empty;
            Copyright = string.Empty;
            Url = string.Empty;
            EncodedBy = string.Empty;
            Mood = string.Empty;
            Rating = string.Empty;
            Quality = string.Empty;
            Bpm = string.Empty;
            Lyrics = string.Empty;
            Conductor = string.Empty;
            Lyricist = string.Empty;
            OriginalLyricist = string.Empty;
            Label = string.Empty;
            RemixedBy = string.Empty;
            RadioStationName = string.Empty;
            AudioFileUrl = string.Empty;
            AuthorUrl = string.Empty;
            AudioSourceUrl = string.Empty;
            RadioStationUrl = string.Empty;
            BuyCdUrl = string.Empty;
            FullPath = path;
        }

        #endregion

        #region Properties.

        public string FullPath { get; set; }
        public string FilePath { get; set; }
        public string FileName { get; set; }
        public string Album { get; set; }
        public string Artist { get; set; }
        public string Albumartist { get; set; }
        public string Title { get; set; }
        public string Year { get; set; }
        public string Genre { get; set; }
        public string Comment { get; set; }
        public string TrackNumber { get; set; }
        public string DiscNumber { get; set; }
        public string Catalog { get; set; }
        public string Isrc { get; set; }
        public string ReleaseType { get; set; }
        public string Composer { get; set; }
        public string Originalartist { get; set; }
        public string Copyright { get; set; }
        public string Url { get; set; }
        public string EncodedBy { get; set; }
        public string Mood { get; set; }
        public string Rating { get; set; }
        public string Quality { get; set; }
        public string Bpm { get; set; }
        public bool Compilation { get; set; }
        public string Lyrics { get; set; }
        public string Conductor { get; set; }
        public string Lyricist { get; set; }
        public string OriginalLyricist { get; set; }
        public string Label { get; set; }
        public string RemixedBy { get; set; }
        public string RadioStationName { get; set; }
        public string AudioFileUrl { get; set; }
        public string AuthorUrl { get; set; }
        public string AudioSourceUrl { get; set; }
        public string RadioStationUrl { get; set; }
        public string BuyCdUrl { get; set; }
        

        public bool HasFileCoverArt
        {
            get { return ArtImage != null; }
        }
        
        public long Size { get; set; }
        public Image ArtImage { get; set; }
        public byte[] ArtByteArray { get; set; }
        public long ArtSize { get; set; }
        public string Time { get; set; }
        public string BitRate { get; set; }
        public int Channels { get; set; }
        public string SampleRate { get; set; }
        public long TimeTicks { get; set; }
        public string BitsPerSample { get; set; }
        public string Encoder { get; set; }

        public bool IsArtistChanged { get; set; }
        public bool IsYearChanged { get; set; }
        public bool IsAlbumChanged { get; set; }
        public bool IsTitleChanged { get; set; }
        public bool IsGenreChanged { get; set; }
        public bool IsCommentChanged { get; set; }
        public bool IsTrackNumberChanged { get; set; }
        public bool IsDiscNumberChanged { get; set; }
        public bool IsCatalogChanged { get; set; }
        public bool IsIsrcChanged { get; set; }
        public bool IsReleaseTypeChanged { get; set; }
        public bool IsAlbumArtistChanged { get; set; }
        public bool IsComposerChanged { get; set; }
        public bool IsOriginalArtistChanged { get; set; }
        public bool IsCopyrightChanged { get; set; }
        public bool IsUrlChanged { get; set; }
        public bool IsEncodedByChanged { get; set; }
        public bool IsMoodChanged { get; set; }
        public bool IsRatingChanged { get; set; }
        public bool IsQualityChanged { get; set; }
        public bool IsBpmChanged { get; set; }
        public bool IsCompilationChanged { get; set; }
        public bool IsCoverArtChanged { get; set; }
        public bool IsLyricsChanged { get; set; }
        public bool IsLyricistChanged { get; set; }
        public bool IsOriginalLyricistChanged { get; set; }
        public bool IsConductorChanged { get; set; }
        public bool IsLabelChanged { get; set; }
        public bool IsRemixedByChanged { get; set; }
        public bool IsRadioStationNameChanged { get; set; }
        public bool IsAudioFileUrlChanged { get; set; }
        public bool IsAudioSourceUrlChanged { get; set; }
        public bool IsAuthorUrlChanged { get; set; }
        public bool IsBuyCdUrlChanged { get; set; }
        public bool IsRadioStationUrlChanged { get; set; }

        public TrackRename Trackrename { get; set; }

        public string OldFileName
        {
            get { return Trackrename.OriginalFileName; }
        }

        public string OldPath
        {
            get { return Trackrename.OriginalPath; }
        }

        public string NewFileName
        {
            get { return Trackrename.RenamedFileName; }
        }

        public string NewPath
        {
            get { return Trackrename.RenamedPath; }
        }

        public bool IsTrackRenamed
        {
            get { return Trackrename != null; }
        }

        #endregion

        #region Public Methods

        public int TrimTrailingWhitespaces()
        {
            int counter = 0;

            //Trim the artist tag
            if (!string.IsNullOrEmpty(Artist) && Char.IsWhiteSpace(Artist[Artist.Length - 1]))
            {
                Artist = Artist.TrimEnd();
                IsArtistChanged = true;
                counter++;
            }

            //Trim the album artist tag
            if (!string.IsNullOrEmpty(Albumartist) && Char.IsWhiteSpace(Albumartist[Albumartist.Length - 1]))
            {
                Albumartist = Albumartist.TrimEnd();
                IsAlbumArtistChanged = true;
                counter++;
            }

            //Trim the album tag
            if (!string.IsNullOrEmpty(Album) && Char.IsWhiteSpace(Album[Album.Length - 1]))
            {
                Album = Album.TrimEnd();
                IsAlbumChanged = true;
                counter++;
            }

            //Trim the title tag
            if (!string.IsNullOrEmpty(Title) && Char.IsWhiteSpace(Title[Title.Length - 1]))
            {
                Title = Title.TrimEnd();
                IsTitleChanged = true;
                counter++;
            }

            //Trim year tag
            if (!string.IsNullOrEmpty(Year) && Char.IsWhiteSpace(Year[Year.Length - 1]))
            {
                Year = Year.TrimEnd();
                IsYearChanged = true;
                counter++;
            }

            //Trim the genre tag;
            if (!string.IsNullOrEmpty(Genre) && Char.IsWhiteSpace(Genre[Genre.Length - 1]))
            {
                Genre = Genre.TrimEnd();
                IsGenreChanged = true;
                counter++;
            }

            //Trim the comment tag
            if (!string.IsNullOrEmpty(Comment) && Char.IsWhiteSpace(Comment[Comment.Length - 1]))
            {
                Comment = Comment.TrimEnd();
                IsCommentChanged = true;
                counter++;
            }

            //Trim the catalog tag
            if (!string.IsNullOrEmpty(Catalog) && Char.IsWhiteSpace(Catalog[Catalog.Length - 1]))
            {
                Catalog = Catalog.TrimEnd();
                IsCatalogChanged = true;
                counter++;
            }

            //Trim the track number tag
            if (!string.IsNullOrEmpty(TrackNumber) && Char.IsWhiteSpace(TrackNumber[TrackNumber.Length - 1]))
            {
                TrackNumber = TrackNumber.TrimEnd();
                IsTrackNumberChanged = true;
                counter++;
            }

            //Trim the disc number tag
            if (!string.IsNullOrEmpty(DiscNumber) && Char.IsWhiteSpace(DiscNumber[DiscNumber.Length - 1]))
            {
                DiscNumber = DiscNumber.TrimEnd();
                IsDiscNumberChanged = true;
                counter++;
            }
            else
            {
                DiscNumber = string.Empty;
            }

            //Trim the isrc number tag
            if (!string.IsNullOrEmpty(Isrc) && Char.IsWhiteSpace(Isrc[Isrc.Length - 1]))
            {
                Isrc = Isrc.TrimEnd();
                IsIsrcChanged = true;
                counter++;
            }

            //Trim the release type tag
            if (!string.IsNullOrEmpty(ReleaseType) && Char.IsWhiteSpace(ReleaseType[ReleaseType.Length - 1]))
            {
                ReleaseType = ReleaseType.TrimEnd();
                IsReleaseTypeChanged = true;
                counter++;
            }

            //Trim the composer tag
            if (!string.IsNullOrEmpty(Composer) && Char.IsWhiteSpace(Composer[Composer.Length - 1]))
            {
                Composer = Composer.TrimEnd();
                IsComposerChanged = true;
                counter++;
            }

            //Trim the original artist tag
            if (!string.IsNullOrEmpty(Originalartist) && Char.IsWhiteSpace(Originalartist[Originalartist.Length - 1]))
            {
                Originalartist = Originalartist.TrimEnd();
                IsOriginalArtistChanged = true;
                counter++;
            }

            //Trim the copyright tag
            if (!string.IsNullOrEmpty(Copyright) && Char.IsWhiteSpace(Copyright[Copyright.Length - 1]))
            {
                Copyright = Copyright.TrimEnd();
            }

            //Trim the url tag
            if (!string.IsNullOrEmpty(Url) && Char.IsWhiteSpace(Url[Url.Length - 1]))
            {
                Url = Url.TrimEnd();
                IsUrlChanged = true;
                counter++;
            }

            //Trim the encoded by tag
            if (!string.IsNullOrEmpty(EncodedBy) && Char.IsWhiteSpace(EncodedBy[EncodedBy.Length - 1]))
            {
                EncodedBy = EncodedBy.TrimEnd();
                IsEncodedByChanged = true;
                counter++;
            }

            //Trim the mood tag
            if (!string.IsNullOrEmpty(Mood) && Char.IsWhiteSpace(Mood[Mood.Length - 1]))
            {
                Mood = Mood.TrimEnd();
                IsMoodChanged = true;
                counter++;
            }

            //Trim the rating tag
            if (!string.IsNullOrEmpty(Rating) && Char.IsWhiteSpace(Rating[Rating.Length - 1]))
            {
                Rating = Rating.TrimEnd();
                IsRatingChanged = true;
                counter++;
            }

            //Trim the quality tag
            if (!string.IsNullOrEmpty(Quality) && Char.IsWhiteSpace(Quality[Quality.Length - 1]))
            {
                Quality = Quality.TrimEnd();
                IsQualityChanged = true;
                counter++;
            }

            //Trim the bpm tag
            if (!string.IsNullOrEmpty(Bpm) && Char.IsWhiteSpace(Bpm[Bpm.Length - 1]))
            {
                Bpm = Bpm.TrimEnd();
                IsBpmChanged = true;
                counter++;
            }

            //Trim the lyricist tag
            if (!string.IsNullOrEmpty(Lyricist) && Char.IsWhiteSpace(Lyricist[Lyricist.Length - 1]))
            {
                Lyricist = Lyricist.TrimEnd();
                IsLyricistChanged = true;
                counter++;
            }

            //Trim the original lyricist tag
            if (!string.IsNullOrEmpty(OriginalLyricist) && Char.IsWhiteSpace(OriginalLyricist[OriginalLyricist.Length - 1]))
            {
                OriginalLyricist = OriginalLyricist.TrimEnd();
                IsOriginalLyricistChanged = true;
                counter++;
            }

            //Trim the radio station name tag
            if (!string.IsNullOrEmpty(RadioStationName) && Char.IsWhiteSpace(RadioStationName[RadioStationName.Length - 1]))
            {
                RadioStationName = RadioStationName.TrimEnd();
                IsRadioStationNameChanged = true;
                counter++;
            }

            //Trim the label tag
            if (!string.IsNullOrEmpty(Label) && Char.IsWhiteSpace(Label[Label.Length - 1]))
            {
                Label = Label.TrimEnd();
                IsLabelChanged = true;
                counter++;
            }

            //Trim the conductor tag
            if (!string.IsNullOrEmpty(Conductor) && Char.IsWhiteSpace(Conductor[Conductor.Length - 1]))
            {
                Conductor = Conductor.TrimEnd();
                IsConductorChanged = true;
                counter++;
            }

            //Trim the remixed by tag
            if (!string.IsNullOrEmpty(RemixedBy) && Char.IsWhiteSpace(RemixedBy[RemixedBy.Length - 1]))
            {
                RemixedBy = RemixedBy.TrimEnd();
                IsRemixedByChanged = true;
                counter++;
            }

            //Trim the audio file url tag
            if (!string.IsNullOrEmpty(AudioFileUrl) && Char.IsWhiteSpace(AudioFileUrl[AudioFileUrl.Length - 1]))
            {
                AudioFileUrl = AudioFileUrl.TrimEnd();
                IsAudioFileUrlChanged = true;
                counter++;
            }

            //Trim the audio source url tag
            if (!string.IsNullOrEmpty(AudioSourceUrl) && Char.IsWhiteSpace(AudioSourceUrl[AudioSourceUrl.Length - 1]))
            {
                AudioSourceUrl = AudioSourceUrl.TrimEnd();
                IsAudioSourceUrlChanged = true;
                counter++;
            }

            //Trim the author url tag
            if (!string.IsNullOrEmpty(AuthorUrl) && Char.IsWhiteSpace(AuthorUrl[AuthorUrl.Length - 1]))
            {
                AuthorUrl = AuthorUrl.TrimEnd();
                IsAuthorUrlChanged = true;
                counter++;
            }

            //Trim the buy cd url tag
            if (!string.IsNullOrEmpty(BuyCdUrl) && Char.IsWhiteSpace(BuyCdUrl[BuyCdUrl.Length - 1]))
            {
                BuyCdUrl = BuyCdUrl.TrimEnd();
                IsBuyCdUrlChanged = true;
                counter++;
            }

            //Trim the radio station url tag
            if (!string.IsNullOrEmpty(RadioStationUrl) && Char.IsWhiteSpace(RadioStationUrl[RadioStationUrl.Length - 1]))
            {
                RadioStationUrl = RadioStationUrl.TrimEnd();
                IsRadioStationUrlChanged = true;
                counter++;
            }

            return counter;
        }

        public int TrimLeadingWhitespaces()
        {
            int counter = 0;

            //Trim the artist tag
            if (!string.IsNullOrEmpty(Artist) && Char.IsWhiteSpace(Artist[0]))
            {
                Artist = Artist.TrimStart();
                IsArtistChanged = true;
                counter++;
            }

            //Trim the album artist tag
            if (!string.IsNullOrEmpty(Albumartist) && Char.IsWhiteSpace(Albumartist[0]))
            {
                Albumartist = Albumartist.TrimStart();
                IsAlbumArtistChanged = true;
                counter++;
            }

            //Trim the album tag
            if (!string.IsNullOrEmpty(Album) && Char.IsWhiteSpace(Album[0]))
            {
                Album = Album.TrimStart();
                IsAlbumChanged = true;
                counter++;
            }

            //Trim the title tag
            if (!string.IsNullOrEmpty(Title) && Char.IsWhiteSpace(Title[0]))
            {
                Title = Title.TrimStart();
                IsTitleChanged = true;
                counter++;
            }

            //Trim year tag
            if (!string.IsNullOrEmpty(Year) && Char.IsWhiteSpace(Year[0]))
            {
                Year = Year.TrimStart();
                IsYearChanged = true;
                counter++;
            }

            //Trim the genre tag;
            if (!string.IsNullOrEmpty(Genre) && Char.IsWhiteSpace(Genre[0]))
            {
                Genre = Genre.TrimStart();
                IsGenreChanged = true;
                counter++;
            }

            //Trim the comment tag
            if (!string.IsNullOrEmpty(Comment) && Char.IsWhiteSpace(Comment[0]))
            {
                Comment = Comment.TrimStart();
                IsCommentChanged = true;
                counter++;
            }

            //Trim the catalog tag
            if (!string.IsNullOrEmpty(Catalog) && Char.IsWhiteSpace(Catalog[0]))
            {
                Catalog = Catalog.TrimStart();
                IsCatalogChanged = true;
                counter++;
            }

            //Trim the track number tag
            if (!string.IsNullOrEmpty(TrackNumber) && Char.IsWhiteSpace(TrackNumber[0]))
            {
                TrackNumber = TrackNumber.TrimStart();
                IsTrackNumberChanged = true;
                counter++;
            }

            //Trim the disc number tag
            if (!string.IsNullOrEmpty(DiscNumber) && Char.IsWhiteSpace(DiscNumber[0]))
            {
                DiscNumber = DiscNumber.TrimStart();
                IsDiscNumberChanged = true;
                counter++;
            }
            else
            {
                DiscNumber = string.Empty;
            }

            //Trim the isrc number tag
            if (!string.IsNullOrEmpty(Isrc) && Char.IsWhiteSpace(Isrc[0]))
            {
                Isrc = Isrc.TrimStart();
                IsIsrcChanged = true;
                counter++;
            }

            //Trim the release type tag
            if (!string.IsNullOrEmpty(ReleaseType) && Char.IsWhiteSpace(ReleaseType[0]))
            {
                ReleaseType = ReleaseType.TrimStart();
                IsReleaseTypeChanged = true;
                counter++;
            }

            //Trim the composer tag
            if (!string.IsNullOrEmpty(Composer) && Char.IsWhiteSpace(Composer[0]))
            {
                Composer = Composer.TrimStart();
                IsComposerChanged = true;
                counter++;
            }

            //Trim the original artist tag
            if (!string.IsNullOrEmpty(Originalartist) && Char.IsWhiteSpace(Originalartist[0]))
            {
                Originalartist = Originalartist.TrimStart();
                IsOriginalArtistChanged = true;
                counter++;
            }

            //Trim the copyright tag
            if (!string.IsNullOrEmpty(Copyright) && Char.IsWhiteSpace(Copyright[0]))
            {
                Copyright = Copyright.TrimStart();
            }

            //Trim the url tag
            if (!string.IsNullOrEmpty(Url) && Char.IsWhiteSpace(Url[0]))
            {
                Url = Url.TrimStart();
                IsUrlChanged = true;
                counter++;
            }

            //Trim the encoded by tag
            if (!string.IsNullOrEmpty(EncodedBy) && Char.IsWhiteSpace(EncodedBy[0]))
            {
                EncodedBy = EncodedBy.TrimStart();
                IsEncodedByChanged = true;
                counter++;
            }

            //Trim the mood tag
            if (!string.IsNullOrEmpty(Mood) && Char.IsWhiteSpace(Mood[0]))
            {
                Mood = Mood.TrimStart();
                IsMoodChanged = true;
                counter++;
            }

            //Trim the rating tag
            if (!string.IsNullOrEmpty(Rating) && Char.IsWhiteSpace(Rating[0]))
            {
                Rating = Rating.TrimStart();
                IsRatingChanged = true;
                counter++;
            }

            //Trim the quality tag
            if (!string.IsNullOrEmpty(Quality) && Char.IsWhiteSpace(Quality[0]))
            {
                Quality = Quality.TrimStart();
                IsQualityChanged = true;
                counter++;
            }

            //Trim the bpm tag
            if (!string.IsNullOrEmpty(Bpm) && Char.IsWhiteSpace(Bpm[0]))
            {
                Bpm = Bpm.TrimStart();
                IsBpmChanged = true;
                counter++;
            }

            //Trim the lyricist tag
            if (!string.IsNullOrEmpty(Lyricist) && Char.IsWhiteSpace(Lyricist[0]))
            {
                Lyricist = Lyricist.TrimStart();
                IsLyricistChanged = true;
                counter++;
            }

            //Trim the original lyricist tag
            if (!string.IsNullOrEmpty(OriginalLyricist) && Char.IsWhiteSpace(OriginalLyricist[0]))
            {
                OriginalLyricist = OriginalLyricist.TrimStart();
                IsOriginalLyricistChanged = true;
                counter++;
            }

            //Trim the radio station name tag
            if (!string.IsNullOrEmpty(RadioStationName) && Char.IsWhiteSpace(RadioStationName[0]))
            {
                RadioStationName = RadioStationName.TrimStart();
                IsRadioStationNameChanged = true;
                counter++;
            }

            //Trim the label tag
            if (!string.IsNullOrEmpty(Label) && Char.IsWhiteSpace(Label[0]))
            {
                Label = Label.TrimStart();
                IsLabelChanged = true;
                counter++;
            }

            //Trim the conductor tag
            if (!string.IsNullOrEmpty(Conductor) && Char.IsWhiteSpace(Conductor[0]))
            {
                Conductor = Conductor.TrimStart();
                IsConductorChanged = true;
                counter++;
            }

            //Trim the remixed by tag
            if (!string.IsNullOrEmpty(RemixedBy) && Char.IsWhiteSpace(RemixedBy[0]))
            {
                RemixedBy = RemixedBy.TrimStart();
                IsRemixedByChanged = true;
                counter++;
            }

            //Trim the audio file url tag
            if (!string.IsNullOrEmpty(AudioFileUrl) && Char.IsWhiteSpace(AudioFileUrl[0]))
            {
                AudioFileUrl = AudioFileUrl.TrimStart();
                IsAudioFileUrlChanged = true;
                counter++;
            }

            //Trim the audio source url tag
            if (!string.IsNullOrEmpty(AudioSourceUrl) && Char.IsWhiteSpace(AudioSourceUrl[0]))
            {
                AudioSourceUrl = AudioSourceUrl.TrimStart();
                IsAudioSourceUrlChanged = true;
                counter++;
            }

            //Trim the author url tag
            if (!string.IsNullOrEmpty(AuthorUrl) && Char.IsWhiteSpace(AuthorUrl[0]))
            {
                AuthorUrl = AuthorUrl.TrimStart();
                IsAuthorUrlChanged = true;
                counter++;
            }

            //Trim the buy cd url tag
            if (!string.IsNullOrEmpty(BuyCdUrl) && Char.IsWhiteSpace(BuyCdUrl[0]))
            {
                BuyCdUrl = BuyCdUrl.TrimStart();
                IsBuyCdUrlChanged = true;
                counter++;
            }

            //Trim the radio station url tag
            if (!string.IsNullOrEmpty(RadioStationUrl) && Char.IsWhiteSpace(RadioStationUrl[0]))
            {
                RadioStationUrl = RadioStationUrl.TrimStart();
                IsRadioStationUrlChanged = true;
                counter++;
            }

            return counter;
        }

        #endregion

        #region Internal Methods.

        internal void SetPropValue(string propName, string value)
        {
            Type type = GetType();

            PropertyInfo senderProperty = type.GetProperty(propName);

            senderProperty.SetValue(this, value, null);
        }

        internal object GetPropValue(string propName)
        {
            Type type = GetType();

            PropertyInfo senderProperty = type.GetProperty(propName);

            return senderProperty.GetValue(this, null);
        } 

        #endregion

        #region Virtual Methods.

        public virtual void ClearTags(){}

        public virtual bool RenameTrack(MaskHelperCollection masks, TrackRename trackRename)
        {
            return false;
        }

        public virtual void SaveFrontCoverArt(byte[] bytes){}

        public virtual void RemoveFrontCoverArt(){}

        public virtual void SetTag(params string[] tagtype){}

        public virtual void SetTag(string tagtype){}

        public virtual string GetTag(string tagtype)
        {
            return null;
        }

        public virtual void CopyTag(string tagtype, string value, string toPropertyName){}

        public virtual void SwapTag(string tagtypeFrom, string valueFrom, string propertyNameFrom, string tagtypeTo, string valueTo, string propertyNameTo) { }

        public virtual void SetTags(Id3Actions id3Actions){}

        public virtual void ClearUndo(){}

        public virtual void UpdateAfterRename(){}

        public virtual bool IsEmpty { get; set; }

        public abstract string TrackFormat { get; }

        public abstract bool IsSupportedTag { get; }

        public abstract bool IsTagCorrupt(out string message);

        #endregion
    }
}
